﻿// Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
// This is sample code only, do not use in production environments

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Xml;
using System.Xml.Linq;
using Microsoft.TeamFoundation.Framework.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Server;

namespace Microsoft.ALMRangers.TFSKanbanGuidance.GlobalListUpdater
{
    public class TFSFunctions
    {
        #region TFS Basic functions
        public static string GetTeamProjectCollectionUrl(string requestContextVirtualDirectory, string workItemChangedEventDisplayUrl)
        {
            string[] strArray = workItemChangedEventDisplayUrl.Split('/');
            return String.Format("{0}//{1}{2}", strArray[0],strArray[2], requestContextVirtualDirectory);
        }
        
        public static TfsTeamProjectCollection GetTeamProjectCollection(string requestContextVirtualDirectory, string workItemChangedEventDisplayUrl)
        {
            string tpcUrl = GetTeamProjectCollectionUrl(requestContextVirtualDirectory, workItemChangedEventDisplayUrl);
            var collection = new TfsTeamProjectCollection(new Uri(tpcUrl));
            collection.EnsureAuthenticated();
            return collection;
        }        
        
        public static WorkItemStore GetWorkItemStore(TfsTeamProjectCollection collection)
        {
            return (WorkItemStore)collection.GetService(typeof(WorkItemStore));
        }        
        
        public static WorkItemCollection ExecuteQuery(WorkItemStore store, string query, string teamProjectName, string processStepWorkItemType)
        {
            query = query.ToLower().Replace("@project", teamProjectName);
            query = query.ToLower().Replace("@processstepworkitemtype", processStepWorkItemType);
            return store.Query(query);
        }
        #endregion

        #region Global Lists functions
        public static XmlDocument ExportGlobalLists(WorkItemStore store)
        {
            return store.ExportGlobalLists();
        }

        public static void ImportGlobalList(WorkItemStore store, XmlDocument document)
        {
            store.ImportGlobalLists(document.DocumentElement);
        }

        public static XmlDocument ReplaceGlobalListItems(XmlDocument document, string globalList, List<string> globalListItems, Project teamProject, WorkItemStore store, string originalGlobalList, out bool updateWITD)
        {
            var doc = XDocument.Parse(document.OuterXml);
            var globalListElement = GetGlobalListElement(doc, globalList);
            updateWITD = false;

            if (globalListElement == null)
            {
                updateWITD = true;
                globalListElement = new XElement("GLOBALLIST", new XAttribute("name", globalList));
                doc.Root.Add(globalListElement);
            }
            else
            {
                globalListElement.RemoveNodes();
            }

            foreach (string listItem in globalListItems)
            {
                globalListElement.Add(new XElement("LISTITEM", new XAttribute("value", listItem)));
            }

            var newXmlDocument = new XmlDocument();
            newXmlDocument.InnerXml = doc.ToString();
            return newXmlDocument;
        }

        internal static XElement GetGlobalListElement(XDocument doc, string globalList)
        {
            var globalListElement =
                (from el in doc.Root.Descendants()
                 where (string)el.Attribute("name") == globalList
                 select el).FirstOrDefault();
            return globalListElement;
        }
        #endregion

        #region WITD functions
        internal static XmlDocument ExportWITD(Project teamProject, string workItemType)
        {
            XmlDocument definition = teamProject.WorkItemTypes[workItemType].Export(false);
            return definition;
        }

        internal static void ImportWITD(Project teamProject, XmlDocument definition)
        {
            WorkItemType.Validate(teamProject, definition.InnerXml);
            teamProject.WorkItemTypes.Import(definition.InnerXml);
        }

        internal static XmlDocument UpdateAllowedValuesInWITD(XmlDocument definition, string originalGlobalList, string newGlobalList)
        {
            var doc = XDocument.Parse(definition.OuterXml);
            var globalListElement =
                (from el in doc.Root.Descendants()
                 where el.Name.LocalName.ToUpper() == "GLOBALLIST" && (string)el.Attribute("name") == originalGlobalList
                 select el).FirstOrDefault();
            if (globalListElement != null)
            {
                globalListElement.Attribute("name").Value = newGlobalList;
            }
            definition.InnerXml = doc.ToString();
            return definition;
        }

        public static void UpdateWITD(Project teamProject, WorkItemStore store, string originalGlobalList, string newGlobalList)
        {
            foreach (string witd in Properties.Settings.Default.WorkItemTypesToChangeAllowedValues.Split(','))
            {
                XmlDocument definition = ExportWITD(teamProject, witd);
                UpdateAllowedValuesInWITD(definition, originalGlobalList, newGlobalList);
                ImportWITD(teamProject, definition);
            }
        }
        #endregion

    }
}
